const crypto = require('crypto')
global.navigator = {appName: 'nodejs'}; // fake the navigator object
global.window = {};     // fake the window object
const {JSEncrypt} = require('jsencrypt');

function md5(s) {
    return crypto.createHash('md5').update('' + s).digest('hex');
}

function base64Encode(s) {
    return Buffer.from(s).toString('base64');
}

function base64Decode(s) {
    return Buffer.from(s, 'base64').toString('ascii')
}

/**
 * 3des/ECB/NoPadding
 * crypto.desEncryptBase64({algorithm : 'des-ede3', autoPadding : false, key : 'key', plaintext : 'text', iv : null})
 */

function desEncryptBase64(encodeParam) {
    try {
        let plain = encodeParam.plaintext.toString();
        //encrypt
        const iv = new Buffer(encodeParam.iv ? encodeParam.iv : 0);
        const cipher = crypto.createCipheriv(encodeParam.algorithm, encodeParam.key, iv);
        cipher.setAutoPadding(encodeParam.autoPadding)  //default true
        let ciphertext = cipher.update(plain, 'utf8', 'base64');
        ciphertext += cipher.final('base64');
        console.log("crypto data success: algorithm(%s),plaintext(%s),ciphertext(%s)",
                    encodeParam.algorithm, plain, ciphertext);
        return ciphertext;
    } catch (err) {
        console.log("crypto data failed: " + err);
        return null;
    }
}

/**
 * 3des/ECB/NoPadding
 * crypto.desEncryptHex({algorithm : 'des-ede3', autoPadding : false, key : 'key', plaintext : 'text', iv : null})
 */

function desEncryptHex(encodeParam) {
    try {
        let plain = encodeParam.plaintext.toString();
        //encrypt
        const iv = new Buffer(encodeParam.iv ? encodeParam.iv : 0);
        const cipher = crypto.createCipheriv(encodeParam.algorithm, encodeParam.key, iv);
        cipher.setAutoPadding(encodeParam.autoPadding)  //default true
        let ciphertext = cipher.update(plain, 'utf8', 'hex');
        ciphertext += cipher.final('hex');
        console.log("crypto data success: algorithm(%s),plaintext(%s),ciphertext(%s)",
                    encodeParam.algorithm, plain, ciphertext);
        return ciphertext.toUpperCase();
    } catch (err) {
        console.log("crypto data failed: " + err);
        return null;
    }
}

function rsaEncrypt(publicKey, text) {
    let encrypt = new JSEncrypt();
    encrypt.setPublicKey(publicKey);
    return encrypt.encrypt(text);
}

module.exports = {
    md5,
    base64Encode,
    base64Decode,
    desEncryptBase64,
    desEncryptHex,
    rsaEncrypt
}